/**
 * FormFieldDropdownSearch
 */
layui.define(['FormField', 'yunj', 'jquery'], function (exports) {

    let FormField = layui.FormField;
    let win = window;
    let doc = document;
    let $ = layui.jquery;

    class FormFieldDropdownSearch extends FormField {

        constructor(options = {}) {
            super(options);
            this.show_box_el = null;
            this.items_box_el = null;
            this.icon_el = null;
            this.filter_box_el = null;
            this.xhr = null;                          // 数据请求对象
            this.filter_keywords_change_search_timer = null;    // 关键字改变引起的搜索items的定时器
        }

        defineExtraArgs() {
            let that = this;
            return {
                url: "",
                multi: true,
                disabled: false
            };
        }

        defineBoxHtml() {
            let that = this;
            return `<div class="layui-form-item yunj-form-item yunj-form-dropdown-search" id="${that.id}">__layout__</div>`;
        }

        layoutControl() {
            let that = this;
            let controlHtml = `<div class="show-box">
                                    <div class="items-box"></div>
                                    <i class="layui-icon layui-icon-triangle-d"></i>
                                </div><div class="filter-box"></div>`;
            return `<div class="layui-input-inline yunj-form-item-control">${controlHtml}</div>`;
        }

        renderDone() {
            let that = this;
            that.show_box_el = that.fieldBoxEl.find('.show-box');
            that.items_box_el = that.fieldBoxEl.find('.items-box');
            that.icon_el = that.fieldBoxEl.find('.layui-icon-triangle-d');
            that.filter_box_el = that.fieldBoxEl.find('.filter-box');
        }

        setValue(val = '') {
            let that = this;
            that.items_box_el.html('');

            if (yunj.isScalar(val) && val)
                val = yunj.isJson(val) ? JSON.parse(val) : (yunj.isString(val) && val.indexOf(",") !== -1 ? val.split(",") : [val]);
            if (!yunj.isArray(val)) val = [];

            that.items_box_el.html("");
            if (val.length <= 0) return;
            that.request({ids: val.join(',')}).then(items => {
                that.itemsAppend(items);
            });
        }

        getValue() {
            let that = this;
            let itemsEl = that.items_box_el.find('.item');
            if (itemsEl.length <= 0) return "";

            let val = [];
            itemsEl.each(function () {
                val.push($(this).data('value').toString());
            });
            if (val.length <= 0) return "";
            return that.args.multi ? val : val[0];
        }

        itemsAppend(items) {
            let that = this;
            if (!yunj.isObj(items) || yunj.isEmptyObj(items)) return false;
            let itemsContent = '';
            for (let k in items) {
                if (!items.hasOwnProperty(k)) continue;
                let txt = items[k];
                let remove = that.args.disabled ? '' : '<i class="layui-icon layui-icon-close-fill item-remove" title="删除"></i>';
                itemsContent += `<div class="item" data-value="${k}">
                                    <span class="txt" title="${txt}">${txt}</span>
                                    ${remove}
                                </div>`;
            }
            that.items_box_el.append(itemsContent);
        }

        request(param = {}) {
            let that = this;
            param = yunj.objSupp(param, {
                keywords: '',
                ids: '',
            });
            $(doc).trigger(`yunj_form_field_${that.id}_request_param`, [param]);
            let url = yunj.urlPushParam(that.args.url, param);
            if (that.xhr) that.xhr.abort();
            return new Promise((resolve, reject) => {
                that.xhr = new XMLHttpRequest();
                that.xhr.open('GET', url, true);
                that.xhr.responseType = 'json';
                that.xhr.onload = function () {
                    if (that.xhr.status !== 200) {
                        reject(that.xhr.status);
                        return false;
                    }
                    let res = that.xhr.response;
                    if (res.errcode !== 0) {
                        reject(res.msg);
                        return false;
                    }
                    resolve(res.data);
                };
                that.xhr.send();
            });
        }

        // 展开筛选
        openFilterBox() {
            let that = this;
            that.icon_el.removeClass('icon-down').addClass('icon-up').css({"transform": `rotate(180deg)`});
            let top = that.show_box_el.offset().top + that.show_box_el.outerHeight() - $(win).scrollTop();
            let keywordsContent = `<input type="text" class="layui-input" name="keywords" placeholder="关键词" autocomplete="off">`;
            let dlItemsContent = `<dl class="items-box"></dl>`;
            let searchBoxContent = ``;
            // 上下定位
            let isUp = top + 300 > $(win).height() && top >= 300;
            if (isUp) {
                that.filter_box_el.css({'top': '', 'bottom': '35px'});
                searchBoxContent = dlItemsContent + keywordsContent;
            } else {
                that.filter_box_el.css({'top': '35px', 'bottom': ''});
                searchBoxContent = keywordsContent + dlItemsContent;
            }
            that.filter_box_el.html(searchBoxContent);
            that.filter_box_el.find(".layui-input").css(isUp ? "borderTopWidth" : "borderBottomWidth", "1px");
            that.filter_box_el.show();
            that.renderFilterItems();
        }

        // 关闭筛选
        closeFilterBox() {
            let that = this;
            that.icon_el.removeClass('icon-up').addClass('icon-down').css({"transform": `rotate(0deg)`});
            that.filter_box_el.hide();
        }

        // 渲染筛选items
        renderFilterItems() {
            let that = this;
            that.filter_box_el.find('.items-box').html(`<dd>搜索中...</dd>`);
            that.render_filter_items_exec();
        }

        // 渲染筛选items执行
        render_filter_items_exec() {
            let that = this;
            let filterItemsBox = that.filter_box_el.find('.items-box');
            let filterKeywordsEl = that.filter_box_el.find('input[name=keywords]');
            let param = {keywords: filterKeywordsEl.length > 0 ? filterKeywordsEl.val() : ''};
            that.request(param).then(items => {
                if (items.length <= 0) {
                    filterItemsBox.html(`<dd>暂无内容</dd>`);
                    return true;
                }
                let vals = that.getValue();
                vals = yunj.isArray(vals) ? vals : [vals];
                let itemsContent = '';
                for (let k in items) {
                    if (!items.hasOwnProperty(k)) continue;
                    itemsContent += `<dd class="${vals.indexOf(k) !== -1 ? 'active' : ''}" data-value="${k}" title="${items[k]}">${items[k]}</dd>`;
                }
                filterItemsBox.html(itemsContent);
            });
        }

        defineExtraEventBind() {
            let that = this;

            $(doc).on("click", function () {
                that.closeFilterBox();
            });

            that.fieldBoxEl.on('click', '.show-box', function (e) {
                if (that.args.disabled) return false;
                let isOpen = that.icon_el.hasClass('icon-down') || (!that.icon_el.hasClass('icon-down') && !that.icon_el.hasClass('icon-up'));
                if (isOpen) {
                    that.openFilterBox();
                } else {
                    that.closeFilterBox();
                }
                e.stopPropagation();
            });

            that.filter_box_el.on("click", function (e) {
                //e.stopPropagation();
            });

            that.fieldBoxEl.on('keyup', 'input[name=keywords]', function (e) {
                if (that.filter_keywords_change_search_timer) clearTimeout(that.filter_keywords_change_search_timer);
                that.filter_keywords_change_search_timer = setTimeout(function () {
                    that.renderFilterItems();
                }, 500);
            });

            that.fieldBoxEl.on('click', 'input[name=keywords]', function (e) {
                e.stopPropagation();
            });

            that.fieldBoxEl.on('click', '.filter-box dd', function (e) {
                let dd = $(this);
                if (dd.hasClass('active')) return false;
                if (!that.args.multi) {
                    that.filter_box_el.find('dd').removeClass('active');
                    that.items_box_el.html('');
                }
                let items = {[dd.data('value')]: dd.attr('title')};
                dd.addClass('active');
                that.itemsAppend(items);
                e.stopPropagation();
            });

            that.fieldBoxEl.on('click', '.show-box .item', function (e) {
                yunj.copy($(this).find('.txt').text());
                e.stopPropagation();
            });

            that.fieldBoxEl.on('click', '.item-remove', function (e) {
                if (that.args.disabled) return false;
                let itemEl = $(this).parent(".item");
                that.filter_box_el.find(`dd[data-value=${itemEl.data("value")}]`).removeClass("active");
                itemEl.remove();
                e.stopPropagation();
            });

        }

    }

    exports('FormFieldDropdownSearch', FormFieldDropdownSearch);
});